package telin;

import gate.Annotation;
import gate.AnnotationSet;
import gate.Node;
import gate.creole.ANNIEConstants;

import telin.RusApoldaConstants;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;

/**
*
* @author Telematica Instituut, Christian Wartena
*/

public class Content {
    private Annotation tokArray[];
    private int tokIdx = 0;
    private int startTokIdx = -1;
    private int charIdx = 0;
    private int nrOfTokens = 0;
    private String tokenString = "";
    private String lemmaFeature;
    //private char currentChar;
    private Stack choicepoints;
    
    
    private Annotation[] getTokenArray(AnnotationSet annSet) {
      ArrayList tokens = new ArrayList();
      Annotation tokArray[];

        AnnotationSet tokenAS = annSet.get(RusApoldaConstants.TOKEN_ANNOTATION_TYPE);
                                          //RusApoldaConstants

//      AnnotationSet tokenAS = annSet.get(ANNIEConstants.TOKEN_ANNOTATION_TYPE);


      Node x = tokenAS.firstNode();
      while(x != tokenAS.lastNode()) {
        Iterator annIt = tokenAS.get(x.getOffset()).iterator();
        while(annIt.hasNext()) {
          Annotation ann = (Annotation) annIt.next();
          if(x == ann.getStartNode()) {
            tokens.add(ann);
//           VOVKA EDIT
//             break;
          }
        }
        x = tokenAS.nextNode(x);
      }
      tokArray = new Annotation[tokens.size()];
      tokArray = (Annotation[]) tokens.toArray(tokArray);

      return tokArray;
    }

    public Content(AnnotationSet annSet, String lemmaFeature)
    {
      tokArray = getTokenArray(annSet);
      nrOfTokens = tokArray.length;
      choicepoints = new Stack();
      this.lemmaFeature = lemmaFeature;
        
//      forward();
    }

    public boolean more() {
        return charIdx < tokenString.length() || tokIdx + 1 < nrOfTokens;
    }

    public void forward(FSMState state)
    {
        String lemmaString;
              startTokIdx++;
              tokIdx = startTokIdx;
              choicepoints.clear();
              if(startTokIdx < nrOfTokens)
              {
                tokenString = (String)tokArray[startTokIdx].getFeatures().get(RusApoldaConstants.TOKEN_STRING_FEATURE_NAME);
                if(lemmaFeature != null)
                {
                  lemmaString = (String)tokArray[tokIdx].getFeatures().get(lemmaFeature);
                  if(lemmaString != null && !lemmaString.equalsIgnoreCase(tokenString))
                  { //TODO there could be more than one possible stem. This should become a while-loop
                    choicepoints.push(new Choicepoint(tokIdx,state));
                  }
                }
              }
              else
              {
                tokenString = "";
              }
              charIdx = 0;


      /*  String lemmaString;
      startTokIdx++;
      tokIdx = startTokIdx;
      choicepoints.clear();
      if(startTokIdx < nrOfTokens) {
        tokenString = (String)tokArray[startTokIdx].getFeatures().get(ANNIEConstants.TOKEN_STRING_FEATURE_NAME);
          if(lemmaFeature != null){
              lemmaString = (String)tokArray[tokIdx].getFeatures().get(lemmaFeature);
              if(lemmaString != null && !lemmaString.equalsIgnoreCase(tokenString)) {

                  //TODO there could be more than one possible stem. This should become a while-loop
                choicepoints.push(new Choicepoint(tokIdx,state));
              }
        }

      } else {
        tokenString = "";
      }
      charIdx = 0;
        */

    }

    public FSMState redo() {
      if(choicepoints.isEmpty())
        return null;
      else
      {
        Choicepoint p = (Choicepoint) choicepoints.pop();
        if(p.getTokIdx() >= 0 && lemmaFeature != null)
        {
          tokIdx = p.getTokIdx();
          tokenString = (String)tokArray[tokIdx].getFeatures().get(lemmaFeature);
        }
        charIdx = 0;

        return p.getState();
      }
    }

    public boolean atEndOfWord() {
      return charIdx == tokenString.length();
    }

    public char getNextChar(FSMState state) {


        String lemmaString;
              char rc = ' ';
              if(charIdx < tokenString.length()) {
                rc = tokenString.charAt(charIdx);
                charIdx++;
              } else {
                if(tokIdx + 1 < nrOfTokens) {
                  tokIdx++;
                  tokenString = (String)tokArray[tokIdx].getFeatures().get(RusApoldaConstants.TOKEN_STRING_FEATURE_NAME);
                  if(!tokArray[tokIdx].getFeatures().get(RusApoldaConstants.TOKEN_KIND_FEATURE_NAME).equals("word")) {
                    choicepoints.push(new Choicepoint(state));
                  } else {
                    if(lemmaFeature != null) {
                      lemmaString = (String)tokArray[tokIdx].getFeatures().get(lemmaFeature);
                      if(lemmaString != null && !lemmaString.equalsIgnoreCase(tokenString)) { //TODO there could be more than one possible stem. This should become a while-loop
                        choicepoints.push(new Choicepoint(tokIdx,state));
                      }
                    }

                    if(!tokArray[tokIdx-1].getFeatures().get(RusApoldaConstants.TOKEN_KIND_FEATURE_NAME).equals("word")) {
                      choicepoints.push(new Choicepoint(state));
                    }
                  }
                } else {
                  tokenString = "";
                }
                charIdx = 0;
              }
              return rc;

       /* String lemmaString;
      char rc = ' ';
      if(charIdx < tokenString.length()) {
        rc = tokenString.charAt(charIdx);
        charIdx++;
      } else {
        if(tokIdx + 1 < nrOfTokens) {
          tokIdx++;
          tokenString = (String)tokArray[tokIdx].getFeatures().get(ANNIEConstants.TOKEN_STRING_FEATURE_NAME);
          if(! (tokArray[tokIdx].getFeatures().get(ANNIEConstants.TOKEN_KIND_FEATURE_NAME).equals("С") ||
          tokArray[tokIdx].getFeatures().get(ANNIEConstants.TOKEN_KIND_FEATURE_NAME).equals("П") ))
          {
                      choicepoints.push(new Choicepoint(state));

        if(lemmaFeature != null){
              lemmaString = (String)tokArray[tokIdx].getFeatures().get(lemmaFeature);
              if(lemmaString != null && !lemmaString.equalsIgnoreCase(tokenString)) {

                  //TODO there could be more than one possible stem. This should become a while-loop
                choicepoints.push(new Choicepoint(tokIdx,state));
              }
        }
            if(!! (tokArray[tokIdx].getFeatures().get(ANNIEConstants.TOKEN_KIND_FEATURE_NAME).equals("С") ||
          tokArray[tokIdx].getFeatures().get(ANNIEConstants.TOKEN_KIND_FEATURE_NAME).equals("П") )) {
              choicepoints.push(new Choicepoint(state));
            }
        }
        } else {
          tokenString = "";
        }
        charIdx = 0;
      }
      return rc;*/

    }
      
    public Region getCurrentRegion() {

      return new Region(
           tokArray[startTokIdx].getStartNode().getOffset().intValue(),
           tokArray[tokIdx].getEndNode().getOffset().intValue()-1); 
    }
    
}
